package cn.ycc1.functionlibrary.reflection;

/**
 * Working with Arrays
 * @author ycc
 * @date 2025/3/9
 * Arrays are implemented in the Java virtual machine. The only methods on arrays are those inherited from Object. The length of
 * an array is not part of its type; arrays have a length field which is accessible via Array.getLength(Object).
 *
 * Reflection provides methods for accessing array types and array component types, creating new arrays, and retrieving and
 * setting array component values.
 */
public class WorkingWithArrays {
    /**
     * Identifying Array Types
     * Array types may be identified by invoking Class.isArray().
     *
     * You can get the exact type of the internal array on a String object with the following code.
     *
     * Class<?> c = String.class;
     * Field field = c.getDeclaredField("value");
     *
     * Class<?> fieldType = field.getType();
     * boolean isArray = fieldType.isArray();
     * System.out.println("isArray = " + isArray);
     *
     * Class<?> elementType = fieldType.getComponentType();
     * System.out.println("elementType = " + elementType);
     * Running the previous code prints the following.
     *
     * isArray = true
     * elementType = byte
     */

    /**
     * Creating New Arrays
     * Just as in non-reflective code, reflection supports the ability to dynamically create arrays of arbitrary type and
     * dimensions via java.lang.reflect.Array.newInstance().
     *
     * The Array class contains a collection of static method to get reflective information on arrays, as well as to set and
     * read the elements on any array.
     *
     * Let us consider the following code.
     *
     * int length = 10;
     *
     * Object o = Array.newInstance(int.class, 10);
     * boolean isArray = o.getClass().isArray();
     * System.out.println("isArray = " + isArray);
     * Class<?> componentType = o.getClass().getComponentType();
     * System.out.println("componentType = " + componentType);
     * int reflectiveLength = Array.getLength(o);
     * System.out.println("reflectiveLength = " + reflectiveLength);
     *
     * for (int i = 0; i < reflectiveLength; i++) {
     *     Array.set(o, i, 2*i);
     * }
     * System.out.println(Arrays.toString((int[])o));
     * Let us comment this code line by line.
     *
     * Array.newInstance(int.class, 10): creates a new instance of an array of 10 int.
     * o.getClass().isArray(): check if the corresponding class is an array class.
     * o.getClass().getComponentType(): returns the type of the components of this array. In this case, it is int.
     * Array.getLength(o): returns the length of this array.
     * Array.set(o, i, 2*i): reflectively set the i th element of the array o to the value 2*i. You can also reflectively
     * read the i th element of the array o with the Array.get(o, i) method call.
     * Note that the Array class has methods to set primitive values without boxing or unboxing. For example, you can use
     * Array.setDouble() and Array.getDouble() to set and get the elements of an array of double.
     *
     * There are two elements to consider when using these methods.
     *
     * Calling a Array.setFloat() method with a Float object instead of a float primitive type will throw an
     * IllegalArgumentException.
     * Calling Array.setInt() and passing an array of long is OK, as there is no loss of precision when converting an int to a
     * long. The contrary is illegal. You cannot call Array.setLong(), passing an array of int, as it would lead to a loss of
     * precision due to the narrowing of your long.
     * Running the previous code prints the following.
     *
     * isArray = true
     * componentType = int
     * reflectiveLength = 10
     * [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
     * Note that trying to read or write elements at an index greater than the length of this array will throw an
     * ArrayIndexOutOfBoundsException.
     */


}
